package com.dinzeer.legendreliclib.lib.util.impl;

import com.dinzeer.legendreliclib.lib.event.StackChargeEvent;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 特别计数器管理器实现类，处理特别计数器数据的存储和操作。
 * <p>
 * 该类实现了 {@link IStackManager} 接口，提供了具体的特别计数器管理逻辑，包括数据迁移、增减操作等。
 */
public class RegisteredStackManager implements IStackManager {

    /**
     * 效果标识符。
     */
    private final String effectKey;

    /**
     * 最大特别计数器值。
     */
    private final int maxStacks;

    /**
     * 私有构造函数。
     *
     * @param effectKey  效果标识符
     * @param maxStacks  最大特别计数器值
     */
    private RegisteredStackManager(String effectKey, int maxStacks) {
        this.effectKey = effectKey;
        this.maxStacks = maxStacks;
    }

    /**
     * 迁移旧数据格式到新结构。
     *
     * @param rootTag 根 NBT 标签
     */
    private void migrateOldData(CompoundTag rootTag) {
        String oldKey = effectKey + "_Stacks";
        if (rootTag.contains(oldKey)) {
            CompoundTag relicStackTag = rootTag.getCompound("relicstack");
            relicStackTag.putInt(oldKey, rootTag.getInt(oldKey));
            rootTag.put("relicstack", relicStackTag);
            rootTag.remove(oldKey); // 删除旧键
        }
    }

    @Override
    public void addStacks(Player player, int amount) {
        ItemStack weapon = player.getMainHandItem();
        if (weapon.isEmpty() || !weapon.hasTag()) return;

        CompoundTag rootTag = weapon.getOrCreateTag();
        migrateOldData(rootTag); // 迁移旧数据

        // 创建/获取relicstack子标签
        CompoundTag relicStackTag = rootTag.getCompound("relicstack");
        String key = effectKey + "_Stacks";

        StackChargeEvent event = new StackChargeEvent(player, this, amount);
        MinecraftForge.EVENT_BUS.post(event);
        int current = relicStackTag.getInt(key);
        int newValue = Math.min(current + event.amount, maxStacks);

        relicStackTag.putInt(key, newValue);
        rootTag.put("relicstack", relicStackTag); // 更新子标签
    }

    @Override
    public int getCurrentStacks(Player player) {
        if (player.getMainHandItem().isEmpty() || !player.getMainHandItem().hasTag()) return 0;

        CompoundTag rootTag = player.getMainHandItem().getTag();
        migrateOldData(rootTag); // 迁移旧数据

        if (rootTag.contains("relicstack")) {
            CompoundTag relicStackTag = rootTag.getCompound("relicstack");
            return relicStackTag.getInt(effectKey + "_Stacks");
        }
        return 0;
    }

    @Override
    public int getCurrentStacksoffhand(Player player) {
        ItemStack offhand = player.getOffhandItem();
        if (offhand.isEmpty() || !offhand.hasTag()) return 0;

        CompoundTag rootTag = offhand.getTag();
        migrateOldData(rootTag); // 迁移旧数据

        if (rootTag.contains("relicstack")) {
            CompoundTag relicStackTag = rootTag.getCompound("relicstack");
            return relicStackTag.getInt(effectKey + "_Stacks");
        }
        return 0;
    }

    @Override
    public void resetStacks(Player player) {
        ItemStack weapon = player.getMainHandItem();
        if (weapon.isEmpty() || !weapon.hasTag()) return;

        CompoundTag rootTag = weapon.getOrCreateTag();
        migrateOldData(rootTag); // 迁移旧数据

        if (rootTag.contains("relicstack")) {
            CompoundTag relicStackTag = rootTag.getCompound("relicstack");
            relicStackTag.remove(effectKey + "_Stacks");

            // 清理空子标签
            if (relicStackTag.isEmpty()) {
                rootTag.remove("relicstack");
            }
        }
    }

    @Override
    public String getEffectKey() {
        return effectKey;
    }

    @Override
    public int getMaxStacks() {
        return maxStacks;
    }

    @Override
    public String getDescriptionKey() {
        String[] effectKeys = getEffectKey().split(":");
        if (effectKeys.length > 1) {
            return "stack." + effectKeys[0] + "." + effectKeys[1];
        } else {
            return "stack." + getEffectKey();
        }
    }

    /**
     * 注册工厂内部类。
     */
    public static class Registry {
        /**
         * 注册表存储。
         */
        private static final Map<String, RegisteredStackManager> REGISTRY = new ConcurrentHashMap<>();

        /**
         * 注册新的特别计数器管理器。
         *
         * @param effectKey  效果标识符
         * @param maxStacks  最大特别计数器值
         * @return 注册的特别计数器管理器实例
         */
        public static IStackManager register(String effectKey, int maxStacks) {
            return REGISTRY.computeIfAbsent(effectKey,
                    k -> new RegisteredStackManager(effectKey, maxStacks)
            );
        }

        /**
         * 获取已注册的特别计数器管理器。
         *
         * @param effectKey 效果标识符
         * @return 可选的特别计数器管理器实例
         */
        public static Optional<IStackManager> get(String effectKey) {
            return Optional.ofNullable(REGISTRY.get(effectKey));
        }
    }
}